package visiopuce.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import visiopuce.ApplicationContexte;
import visiopuce.HibernateUtil;
import visiopuce.DAO.ChampDAO;
import visiopuce.DAO.ChampDAOImpl;
import visiopuce.DAO.CotationDAO;
import visiopuce.DAO.CotationDAOImpl;
import visiopuce.DAO.ExpFishDAO;
import visiopuce.DAO.ExpFishDAOImpl;
import visiopuce.DAO.HistoriqueDAO;
import visiopuce.DAO.HistoriqueDAOImpl;
import visiopuce.DAO.RenduBiomolDAO;
import visiopuce.DAO.RenduBiomolDAOImpl;
import visiopuce.DAO.RenduFishDAO;
import visiopuce.DAO.RenduFishDAOImpl;
import visiopuce.DAO.RenduPuceDAO;
import visiopuce.DAO.RenduPuceDAOImpl;
import visiopuce.DAO.ResultatDAO;
import visiopuce.DAO.ResultatDAOImpl;
import visiopuce.DAO.VerifBiomolDAO;
import visiopuce.DAO.VerifBiomolDAOImpl;
import visiopuce.DAO.VerifFishDAO;
import visiopuce.DAO.VerifFishDAOImpl;
import visiopuce.DAO.ZoneTesteeBiomolDAO;
import visiopuce.DAO.ZoneTesteeBiomolDAOImpl;
import visiopuce.objets.Champ;
import visiopuce.objets.Cotation;
import visiopuce.objets.ExpFish;
import visiopuce.objets.Historique;
import visiopuce.objets.Puce;
import visiopuce.objets.RenduBiomol;
import visiopuce.objets.RenduFish;
import visiopuce.objets.RenduPuce;
import visiopuce.objets.Resultat;
import visiopuce.objets.TypeCotation;
import visiopuce.objets.VerifBiomol;
import visiopuce.objets.VerifFish;
import visiopuce.objets.ZoneTesteeBiomol;

public class ResultatServiceImpl implements ResultatService {

	private ResultatDAO resultatDAO = ResultatDAOImpl.getInstance();
	private HistoriqueDAO historiqueDAO = HistoriqueDAOImpl.getInstance();
	private CotationDAO cotationDAO = CotationDAOImpl.getInstance();

	private VerifFishDAO verifFishDAO = VerifFishDAOImpl.getInstance();
	private VerifBiomolDAO verifBiomolDAO = VerifBiomolDAOImpl.getInstance();

	private RenduPuceDAO renduPuceDAO = RenduPuceDAOImpl.getInstance();
	private RenduFishDAO renduFishDAO = RenduFishDAOImpl.getInstance();
	private RenduBiomolDAO renduBiomolDAO = RenduBiomolDAOImpl.getInstance();

	private ZoneTesteeBiomolDAO zoneTesteeBiomolDAO = ZoneTesteeBiomolDAOImpl.getInstance();
	private ExpFishDAO expFishDAO = ExpFishDAOImpl.getInstance();

	private ChampDAO champDAO = ChampDAOImpl.getInstance();

	/** Constructeur priv� */
	private ResultatServiceImpl() {
	}

	/** Instance unique non pr�initialis�e */
	private static ResultatServiceImpl INSTANCE = null;

	/** Point d'acc�s pour l'instance unique du singleton */
	public static ResultatService getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new ResultatServiceImpl();
		}
		return INSTANCE;
	}

	public List<Resultat> findAllByidAnalyse(Integer idAnalyse) {
		List<Resultat> resultats = null;

		HibernateUtil.beginTransaction();
		resultats = resultatDAO.findAllByidAnalyse(idAnalyse);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return resultats;
	}

	public void save(Resultat resultat) {
		HibernateUtil.beginTransaction();
		try {
			ArrayList<Cotation> cotations = new ArrayList<Cotation>();
			ArrayList<String> listeCotation = new ArrayList<String>();
			if (resultat.getIdResultat() == 0) {
				if (resultat.getAnalyse().getTypeAnalyse().getLibelle().contains("Puce")) {
					listeCotation = ApplicationContexte.cotationAnalysePuce;
				}
				for (String cotation : listeCotation) {
					List<TypeCotation> tc = ReferentielServiceImpl.getInstance().getTypeCotation(cotation);
					Cotation c = new Cotation();
					c.setDate(new Date());
					c.setTypeCotation(tc.get(0));
					c.setAnalyse(resultat.getAnalyse());
					cotations.add(c);
				}
			}
			resultatDAO.save(resultat);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + resultat.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			for (Cotation cotation : cotations) {
				cotationDAO.save(cotation);
			}
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	public void save(Champ champ) {
		HibernateUtil.beginTransaction();
		try {
			Champ champOld = champDAO.getChampByTypeAndIdObjet(champ.getType(), champ.getIdObjet());
			if (champOld != null) {
				champOld.setValeur(champ.getValeur());
				champ = champOld;
			}
			champDAO.save(champ);
			Historique h2 = new Historique();
			h2.setDate(new Date());
			h2.setRequete("Enregistrement " + champ.toString());
			h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h2);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public List<VerifBiomol> getVerifBiomolByIdAlteration(int idAlt) {
		List<VerifBiomol> verifBM = new ArrayList<VerifBiomol>();

		HibernateUtil.beginTransaction();
		verifBM = verifBiomolDAO.getVerifBiomolByIdAlteration(idAlt);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return verifBM;
	}

	@Override
	public List<VerifFish> getVerifFishByIdAlteration(int idAlt) {
		List<VerifFish> verifFish = new ArrayList<VerifFish>();

		HibernateUtil.beginTransaction();
		verifFish = verifFishDAO.getVerifFishByIdAlteration(idAlt);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return verifFish;
	}

	@Override
	public List<RenduPuce> getResultatPuceByIdPuce(Integer idPuce) {
		List<RenduPuce> rp = null;
		HibernateUtil.beginTransaction();
		rp = renduPuceDAO.getResultatPuceByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return rp;
	}

	@Override
	public List<Resultat> getResultatByIdPuce(Integer idPuce) {
		List<Resultat> rp = null;

		HibernateUtil.beginTransaction();
		rp = resultatDAO.getResultatByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rp;
	}

	@Override
	public List<RenduBiomol> getResultatqPCRByIdPuce(Integer idPuce) {
		List<RenduBiomol> rp = null;

		HibernateUtil.beginTransaction();
		rp = renduBiomolDAO.getResultatqPCRByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rp;
	}

	@Override
	public List<RenduFish> getResultatFishByIdPuce(Integer idPuce) {
		List<RenduFish> rp = null;

		HibernateUtil.beginTransaction();
		rp = renduFishDAO.getResultatFishByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rp;
	}

	@Override
	public String getTypeAnalyseLibelleByidResultat(int idResultat) {
		String libelle = null;

		HibernateUtil.beginTransaction();
		libelle = resultatDAO.getTypeAnalyseLibelleByidResultat(idResultat);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return libelle;
	}

	@Override
	public RenduPuce getRenduPuceByIdResultat(int idResultat) {
		RenduPuce rendu = null;
		HibernateUtil.beginTransaction();
		rendu = renduPuceDAO.getRenduPuceByIdResultat(idResultat);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rendu;
	}

	@Override
	public RenduFish getRenduFishByIdResultat(int idResultat) {
		RenduFish rendu = null;
		HibernateUtil.beginTransaction();
		rendu = renduFishDAO.getRenduFishByIdResultat(idResultat);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rendu;
	}

	@Override
	public RenduBiomol getRenduBioMolByIdResultat(int idResultat) {
		RenduBiomol rendu = null;
		HibernateUtil.beginTransaction();
		rendu = renduBiomolDAO.getRenduBioMolByIdResultat(idResultat);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rendu;
	}

	@Override
	public List<VerifBiomol> getVerifBiomolByRenduBiomol(int idRenduBiomol) {
		List<VerifBiomol> rp = null;

		HibernateUtil.beginTransaction();
		rp = verifBiomolDAO.getVerifBiomolByRenduBiomol(idRenduBiomol);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return rp;
	}

	@Override
	public List<VerifFish> getVerifFishByRenduFish(int idRenduFish) {
		List<VerifFish> rp = null;

		HibernateUtil.beginTransaction();
		rp = verifFishDAO.getVerifFishByRenduFish(idRenduFish);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return rp;
	}

	@Override
	public List<ExpFish> getExpFishByVerif(int idVerifFish) {
		List<ExpFish> ef = null;

		HibernateUtil.beginTransaction();
		ef = expFishDAO.getExpFishByVerif(idVerifFish);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return ef;
	}

	@Override
	public List<ZoneTesteeBiomol> getZoneTesteeBiomolByVerif(int idVerifBiomol) {
		List<ZoneTesteeBiomol> ztbm = null;

		HibernateUtil.beginTransaction();
		ztbm = zoneTesteeBiomolDAO.getZoneTesteeBiomolByVerif(idVerifBiomol);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return ztbm;
	}

	@Override
	public void save(RenduBiomol renduBiomol) {
		HibernateUtil.beginTransaction();
		try {
			renduBiomolDAO.save(renduBiomol);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + renduBiomol.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}

	}

	@Override
	public void save(RenduFish renduFish) {
		HibernateUtil.beginTransaction();
		try {
			renduFishDAO.save(renduFish);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + renduFish.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void save(RenduPuce renduPuce) {
		HibernateUtil.beginTransaction();
		try {
			renduPuceDAO.save(renduPuce);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + renduPuce.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void save(ExpFish expFish) {
		HibernateUtil.beginTransaction();
		try {
			expFishDAO.save(expFish);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + expFish.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void save(ZoneTesteeBiomol zoneTestee) {
		HibernateUtil.beginTransaction();
		try {
			zoneTesteeBiomolDAO.save(zoneTestee);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + zoneTestee.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void save(VerifFish verifFish) {
		HibernateUtil.beginTransaction();
		try {
			verifFishDAO.save(verifFish);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + verifFish.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void save(VerifBiomol verifBiomol) {
		HibernateUtil.beginTransaction();
		try {
			verifBiomolDAO.save(verifBiomol);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement" + verifBiomol.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public void delete(Resultat resultat) {
		HibernateUtil.beginTransaction();
		try {
			RenduBiomol rbm = renduBiomolDAO.getRenduBioMolByIdResultat(resultat.getIdResultat());
			if (rbm != null) {
				List<VerifBiomol> vfs = verifBiomolDAO.getVerifBiomolByRenduBiomol(rbm.getIdRenduBioMol());
				for (VerifBiomol verifBM : vfs) {
					List<ZoneTesteeBiomol> ztbms = zoneTesteeBiomolDAO.getZoneTesteeBiomolByVerif(verifBM.getIdVerifBioMol());
					for (ZoneTesteeBiomol ztbm : ztbms) {
						Historique h2 = new Historique();
						h2.setDate(new Date());
						h2.setRequete("Suppression " + ztbm.toString());
						h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
						historiqueDAO.save(h2);
						ZoneTesteeBiomolDAOImpl.getInstance().delete(ztbm);
					}
					Historique h2 = new Historique();
					h2.setDate(new Date());
					h2.setRequete("Suppression " + verifBM.toString());
					h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
					historiqueDAO.save(h2);
					VerifBiomolDAOImpl.getInstance().delete(verifBM);
				}
				Historique h2 = new Historique();
				h2.setDate(new Date());
				h2.setRequete("Suppression " + rbm.toString());
				h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
				historiqueDAO.save(h2);
				RenduBiomolDAOImpl.getInstance().delete(rbm);
			}

			RenduFish rf = RenduFishDAOImpl.getInstance().getRenduFishByIdResultat(resultat.getIdResultat());
			if (rf != null) {
				List<VerifFish> vfs = VerifFishDAOImpl.getInstance().getVerifFishByRenduFish(rf.getIdRenduFish());
				for (VerifFish verifFish : vfs) {
					List<ExpFish> expFs = ExpFishDAOImpl.getInstance().getExpFishByVerif(verifFish.getIdVerifFish());
					for (ExpFish expF : expFs) {
						Historique h2 = new Historique();
						h2.setDate(new Date());
						h2.setRequete("Suppression " + expF.toString());
						h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
						historiqueDAO.save(h2);
						ExpFishDAOImpl.getInstance().delete(expF);
					}
					Historique h2 = new Historique();
					h2.setDate(new Date());
					h2.setRequete("Suppression " + verifFish.toString());
					h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
					historiqueDAO.save(h2);
					VerifFishDAOImpl.getInstance().delete(verifFish);
				}

				Historique h2 = new Historique();
				h2.setDate(new Date());
				h2.setRequete("Suppression " + rf.toString());
				h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
				historiqueDAO.save(h2);
				RenduFishDAOImpl.getInstance().delete(rf);
			}

			RenduPuce rp = RenduPuceDAOImpl.getInstance().getRenduPuceByIdResultat(resultat.getIdResultat());
			if (rp != null) {
				Historique h2 = new Historique();
				h2.setDate(new Date());
				h2.setRequete("Suppression " + rp.toString());
				h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
				historiqueDAO.save(h2);
				RenduPuceDAOImpl.getInstance().delete(rp);
			}
			Historique h3 = new Historique();
			h3.setDate(new Date());
			h3.setRequete("Suppression " + resultat.toString());
			h3.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h3);

			resultatDAO.delete(resultat);

			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public Resultat getResultatById(int idResultat) {
		Resultat resultat = null;
		HibernateUtil.beginTransaction();
		resultat = resultatDAO.findByID(Resultat.class, idResultat);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return resultat;
	}

	@Override
	public boolean isTermine(Integer idPuce) {
		boolean termine = false;
		HibernateUtil.beginTransaction();
		List<Resultat> resultats = resultatDAO.getResultatByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		for (Resultat res : resultats) {
			if (res.isSigne() && (res.getResultat().contains("Anormal") || res.getResultat().equals("Normal") || res.getResultat().equals("Echec") || res.equals("Annulé"))) {
				termine = true;
				break;
			}
		}
		return termine;
	}

	@Override
	public List<String> getFormuleResultatByIdPuce(Integer idPuce) {

		List<String> rp = null;

		HibernateUtil.beginTransaction();
		rp = resultatDAO.getFormuleResultatByIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();

		return rp;
	}
}